package com.example.demomk.Utils;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.TextUtils;

public class TableDrawer {
    private final Paint paint;
    private final Canvas canvas;
    private final float cellPadding;  // 单元格内边距
    private final float lineSpacing;  // 行间距倍数
    private final int maxLines;       // 最大显示行数（超出显示...）

    public TableDrawer(Canvas canvas, Paint paint, float cellPadding, float lineSpacing, int maxLines) {
        this.canvas = canvas;
        this.paint = new Paint(paint);
        this.cellPadding = cellPadding;
        this.lineSpacing = lineSpacing;
        this.maxLines = maxLines;
    }

    public float drawTable(float startX, float startY,
                          String[] headers, String[][] data,
                          float[] columnWidths) {
        // 1. 计算表格总尺寸
        float tableWidth = calculateTotalWidth(columnWidths);
        float headerHeight = calculateRowHeight(headers, columnWidths);
        float dataHeight = 0;

        // 计算数据区域总高度
        for (String[] row : data) {
            dataHeight += calculateRowHeight(row, columnWidths);
        }

        // 2. 绘制外边框
        drawBorder(startX, startY, tableWidth, headerHeight + dataHeight);

        // 3. 绘制表头
        float currentY = drawRow(startX, startY, headers, columnWidths, true);

        // 4. 绘制数据行
        for (String[] row : data) {
            currentY = drawRow(startX, currentY, row, columnWidths, false);
        }

        return currentY;
    }

    /**
     * 绘制无边框和表头的纯数据表格
     * @param startX 起始X坐标
     * @param startY 起始Y坐标
     * @param data 表格数据（二维数组，每行是一个数据行）
     * @param columnWidths 每列宽度数组
     * @return 表格结束的Y坐标（用于后续绘制其他内容）
     */
    public float drawTableWithoutBorder(float startX, float startY,
                                        String[][] data, float[] columnWidths) {
        float currentY = startY;

        // 逐行绘制数据
        for (String[] row : data) {
            currentY = drawRowWithoutBorder(startX, currentY, row, columnWidths);
        }

        return currentY;
    }

    /**
     * 绘制单行数据（无边框和表头样式）
     */
    private float drawRowWithoutBorder(float startX, float startY,
                                       String[] cells, float[] columnWidths) {
        float maxRowHeight = 0;
        float currentX = startX;

        // 计算行高
        for (int i = 0; i < cells.length; i++) {
            String cellText = cells[i] != null ? cells[i] : "";
            float cellWidth = columnWidths[i] - 2 * cellPadding;
            float cellHeight = calculateCellHeight(cellText, cellWidth);
            maxRowHeight = Math.max(maxRowHeight, cellHeight);
        }

        // 绘制单元格文本
        for (int i = 0; i < cells.length; i++) {
            String cellText = cells[i] != null ? cells[i] : "";
            float cellWidth = columnWidths[i] - 2 * cellPadding;

            drawCellText(
                    cellText,
                    currentX + cellPadding,
                    startY + cellPadding,
                    cellWidth,
                    maxRowHeight - 2 * cellPadding,
                    false  // 非表头样式
            );

            currentX += columnWidths[i];
        }

        return startY + maxRowHeight;
    }

    private float drawRow(float startX, float startY,
                          String[] cells, float[] columnWidths,
                          boolean isHeader) {
        paint.setFakeBoldText(isHeader);
        float maxRowHeight = 0;
        float currentX = startX;

        // 先计算整行的最大高度
        for (int i = 0; i < cells.length; i++) {
            String cellText = cells[i] != null ? cells[i] : "";
            float cellWidth = columnWidths[i] - 2 * cellPadding;
            float cellHeight = calculateCellHeight(cellText, cellWidth);
            maxRowHeight = Math.max(maxRowHeight, cellHeight);
        }

        // 然后绘制单元格内容和分隔线
        for (int i = 0; i < cells.length; i++) {
            String cellText = cells[i] != null ? cells[i] : "";
            float cellWidth = columnWidths[i] - 2 * cellPadding;

            // 绘制单元格文本
            drawCellText(
                    cellText,
                    currentX + cellPadding,
                    startY + cellPadding,
                    cellWidth,
                    maxRowHeight - 2 * cellPadding, // 使用整行高度
                    isHeader
            );

            // 绘制列分隔线（最后一列不画）
            if (i < cells.length - 1) {
                drawVerticalLine(
                        currentX + columnWidths[i],
                        startY,
                        startY + maxRowHeight  // 使用整行高度
                );
            }

            currentX += columnWidths[i];
        }

        // 绘制行分隔线
        drawHorizontalLine(
                startX,
                startY + maxRowHeight,
                calculateTotalWidth(columnWidths)
        );

        return startY + maxRowHeight;
    }

    private void drawCellText(String text, float x, float y,
                              float maxWidth, float maxHeight,
                              boolean isHeader) {
        if (TextUtils.isEmpty(text)) return;

        float textSize = paint.getTextSize();
        float lineHeight = textSize * lineSpacing;
        int maxAllowedLines = (int) (maxHeight / lineHeight);
        int linesToDraw = Math.min(
                calculateLineCount(text, maxWidth),
                Math.min(maxLines, maxAllowedLines)
        );

        int startPos = 0;
        float currentY = y + textSize; // 第一行基线位置

        for (int i = 0; i < linesToDraw && startPos < text.length(); i++) {
            int count = paint.breakText(
                    text, startPos, text.length(),
                    true, maxWidth, null
            );

            // 绘制当前行文本
            canvas.drawText(
                    text, startPos, startPos + count,
                    x, currentY, paint
            );

            startPos += count;

            // 最后一行且文本未显示完，添加省略号
            if (i == linesToDraw - 1 && startPos < text.length()) {
                String ellipsis = "...";
                float ellipsisWidth = paint.measureText(ellipsis);
                if (ellipsisWidth <= maxWidth) {
                    canvas.drawText(
                            ellipsis,
                            x + maxWidth - ellipsisWidth,
                            currentY,
                            paint
                    );
                }
            }

            currentY += lineHeight;
        }
    }

    // ========== 计算辅助方法 ==========
    private float calculateTotalWidth(float[] columnWidths) {
        float total = 0;
        for (float width : columnWidths) total += width;
        return total;
    }

    private float calculateRowHeight(String[] row, float[] columnWidths) {
        float maxHeight = 0;
        for (int i = 0; i < row.length; i++) {
            String text = row[i] != null ? row[i] : "";
            float cellWidth = columnWidths[i] - 2 * cellPadding;
            float cellHeight = calculateCellHeight(text, cellWidth);
            maxHeight = Math.max(maxHeight, cellHeight);
        }
        return maxHeight;
    }

    private float calculateCellHeight(String text, float maxWidth) {
        int lineCount = Math.min(
                calculateLineCount(text, maxWidth),
                maxLines
        );
        return lineCount * paint.getTextSize() * lineSpacing + 2 * cellPadding;
    }

    private int calculateLineCount(String text, float maxWidth) {
        if (paint.measureText(text) <= maxWidth) return 1;

        int lineCount = 0;
        int startPos = 0;

        while (startPos < text.length() && lineCount < maxLines) {
            int count = paint.breakText(
                    text, startPos, text.length(),
                    true, maxWidth, null
            );
            lineCount++;
            startPos += count;
        }

        return lineCount;
    }

    // ========== 绘图辅助方法 ==========
    private void drawBorder(float x, float y, float width, float height) {
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(1f);
        canvas.drawRect(x, y, x + width, y + height, paint);
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(1f);
    }

    private void drawHorizontalLine(float startX, float y, float width) {
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawLine(startX, y, startX + width, y, paint);
        paint.setStyle(Paint.Style.FILL);
    }

    private void drawVerticalLine(float x, float startY, float endY) {
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawLine(x, startY, x, endY, paint);
        paint.setStyle(Paint.Style.FILL);
    }
}